﻿using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Web.Mvc;
using BLL.Security;
using EmitMapper;
using EmitMapper.MappingConfiguration;

namespace Web.Infrastructure.Models
{
    /// <summary>
    /// Base class for models that require mapping functionality to and from POCO objects.
    /// </summary>
    public class BaseModel
    {
        public BaseModel()
        {
            Errors = new List<ErrorModel>();
            var user = EnvironmentContext.User;
            if (user != null)
                CurrentUserId = user.UserId;
        }

        [ScaffoldColumn(false)]
        public IEnumerable<ErrorModel> Errors { get; set; }

        [UIHint("hidden")]
        public string SuccessMessage { get; set; }

        [ScaffoldColumn(false)]
        public int CurrentUserId { get; set; }

        /// <summary>
        /// Maps the specified entity to the specified model.
        /// </summary>
        /// <typeparam name="TEntity">Type of the entity to map.</typeparam>
        /// <typeparam name="TModel">Type of the model to map.</typeparam>
        /// <param name="entity">Instance of the entity to map.</param>
        /// <param name="model">Instance of the model to map the entity to.</param>
        public static void ToModel<TEntity, TModel>(TEntity entity, TModel model)
        {
            var loadMapper = ObjectMapperManager.DefaultInstance.GetMapper<TEntity, TModel>();
            loadMapper.Map(entity, model);
        }

        /// <summary>
        /// Maps the specified model to the specified entity.
        /// </summary>
        /// <typeparam name="TModel">Type of the model to map.</typeparam>
        /// <typeparam name="TEntity">Type of the entity to map.</typeparam>
        /// <param name="model">Instance of the model to map.</param>
        /// <param name="entity">Instance of the entity to map the model to.</param>
        public static TEntity ToEntity<TModel, TEntity>(TModel model, TEntity entity)
        {
            DefaultMapConfig saveConfig = new DefaultMapConfig()
                .ConvertUsing<string, string>(item => item != null ? item.Trim() : null);
            var saveMapper = ObjectMapperManager.DefaultInstance.GetMapper<TModel, TEntity>(saveConfig);
            return saveMapper.Map(model, entity);
        }

        protected static IEnvironmentContext EnvironmentContext
        {
            get
            {
                return DependencyResolver.Current.GetService<IEnvironmentContext>();
            }
        }
    }
}